package main

import (
	"encoding/binary"
	"fmt"
	"math"
	"time"
)

func parseTiny(data []byte, pos *int) (int8, error) {
	if *pos >= len(data) {
		return 0, fmt.Errorf("数据不足以解析TINY")
	}
	val := int8(data[*pos])
	*pos++
	return val, nil
}

func parseShort(data []byte, pos *int) (int16, error) {
	if *pos+2 > len(data) {
		return 0, fmt.Errorf("数据不足以解析SHORT")
	}
	val := int16(binary.LittleEndian.Uint16(data[*pos : *pos+2]))
	*pos += 2
	return val, nil
}

func parseLong(data []byte, pos *int) (int32, error) {
	if *pos+4 > len(data) {
		return 0, fmt.Errorf("数据不足以解析LONG")
	}
	val := int32(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
	*pos += 4
	return val, nil
}

func parseFloat(data []byte, pos *int) (float32, error) {
	if *pos+4 > len(data) {
		return 0, fmt.Errorf("数据不足以解析FLOAT")
	}
	bits := binary.LittleEndian.Uint32(data[*pos : *pos+4])
	*pos += 4
	return math.Float32frombits(bits), nil
}

func parseDouble(data []byte, pos *int) (float64, error) {
	if *pos+8 > len(data) {
		return 0, fmt.Errorf("数据不足以解析DOUBLE")
	}
	bits := binary.LittleEndian.Uint64(data[*pos : *pos+8])
	*pos += 8
	return math.Float64frombits(bits), nil
}

func parseLongLong(data []byte, pos *int) (int64, error) {
	if *pos+8 > len(data) {
		return 0, fmt.Errorf("数据不足以解析LONGLONG")
	}
	val := int64(binary.LittleEndian.Uint64(data[*pos : *pos+8]))
	*pos += 8
	return val, nil
}

func parseVarString(data []byte, pos *int) (string, error) {
	if *pos+1 > len(data) {
		return "", fmt.Errorf("数据不足以解析VAR_STRING长度")
	}
	length := int(data[*pos])
	*pos++

	if *pos+length > len(data) {
		return "", fmt.Errorf("数据不足以解析VAR_STRING内容")
	}
	val := string(data[*pos : *pos+length])
	*pos += length
	return val, nil
}

func parseDate(data []byte, pos *int) (string, error) {
	if *pos+3 > len(data) {
		return "", fmt.Errorf("数据不足以解析DATE")
	}
	year := int(binary.LittleEndian.Uint16(data[*pos : *pos+2]))
	month := int(data[*pos+2])
	day := int(data[*pos+3])
	*pos += 4
	return fmt.Sprintf("%04d-%02d-%02d", year, month, day), nil
}

func parseTime(data []byte, pos *int) (string, error) {
	if *pos+3 > len(data) {
		return "", fmt.Errorf("数据不足以解析TIME")
	}
	negative := data[*pos]&0x80 != 0
	days := int(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
	hours := int(data[*pos+4])
	minutes := int(data[*pos+5])
	seconds := int(data[*pos+6])
	*pos += 7
	sign := ""
	if negative {
		sign = "-"
	}
	return fmt.Sprintf("%s%d %02d:%02d:%02d", sign, days, hours, minutes, seconds), nil
}

func parseDatetime(data []byte, pos *int) (string, error) {
	if *pos+8 > len(data) {
		return "", fmt.Errorf("数据不足以解析DATETIME")
	}
	date, err := parseDate(data, pos)
	if err != nil {
		return "", err
	}
	time, err := parseTime(data, pos)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s %s", date, time), nil
}

func parseTimestamp(data []byte, pos *int) (string, error) {
	if *pos+4 > len(data) {
		return "", fmt.Errorf("数据不足以解析TIMESTAMP")
	}
	unixTime := int64(binary.LittleEndian.Uint32(data[*pos : *pos+4]))
	*pos += 4
	t := time.Unix(unixTime, 0).UTC()
	return t.Format("2006-01-02 15:04:05"), nil
}

func isPrepareResponse(packet []byte) bool {
	// Prepare响应的特征：
	// 1. 第一个字节是0x00（OK包）
	// 2. 接下来是4字节的statement_id
	// 3. 然后是2字节的列数
	// 4. 再然后是2字节的参数数
	// 5. 1字节的填充（0x00）
	// 6. 2字节的警告数

	if len(packet) < 12 {
		return false
	}

	// 检查填充字节是否为0x00
	if packet[9] != 0x00 {
		return false
	}

	// 其他字段应该包含有效的值
	statementID := binary.LittleEndian.Uint32(packet[1:5])
	columnCount := binary.LittleEndian.Uint16(packet[5:7])
	paramCount := binary.LittleEndian.Uint16(packet[7:9])

	// statement_id 应该大于0，列数和参数数可以为0
	return statementID > 0 && (columnCount > 0 || paramCount > 0)
}
